import time

from webutils.layers.services import ManagerProxy

from .. import managers
from .base import BaseService


class RoomService(BaseService):
    user_blacklist = ManagerProxy(managers.UserBlacklist)
    group_blacklist = ManagerProxy(managers.GroupBlacklist)
    room_state = ManagerProxy(managers.RoomState)
    room_heartbeat = ManagerProxy(managers.RoomHeartbeat)

    async def finish(self):
        await self.user_blacklist.clear()
        await self.group_blacklist.clear()
        for state_key in await self.room_state.all():
            state_history = managers.RoomStateHistory(
                self,
                state_key=state_key,
            )
            await state_history.clear()
        await self.room_state.clear()

    async def get_heartbeat_info(self):
        timestamp = await self.room_heartbeat.get_last_ping_time()
        return timestamp

    async def update_state(self, state_dict):
        """
        state_dict = {
            "from": "",
            "to": "",
            "mod": "",
            "msg": {}
        }
        """
        new_value = state_dict
        state_key = new_value['mod']
        new_value['update'] = time.time()
        existed_value = await self.room_state.get(state_key)
        if not existed_value:
            existed_value = new_value
        else:
            if new_value.get('from'):
                existed_value['from'] = new_value['from']
            existed_value['to'] = new_value['to']
            if not isinstance(existed_value.get('msg'), dict):
                existed_value['msg'] = new_value['msg']
            else:
                for key, value in new_value['msg'].items():
                    existed_value['msg'][key] = value
            existed_value['updated_at'] = new_value['updated_at']
        await self.room_state.update(state_key, existed_value)
        history = managers.RoomStateHistory(
            self,
            room_id=self.room_id,
            state_key=state_key,
        )
        await history.append(new_value)

    async def get_state(self):
        return await self.room_state.all()

    async def get_state_history(self, state_key):
        history = managers.RoomStateHistory(
            self,
            room_id=self.room_id,
            state_key=state_key,
        )
        return await history.all()

    async def get_all_state_history(self):
        all_state = await self.room_state.all()
        state_key_lst = all_state.keys()
        dct = {}
        for state_key in state_key_lst:
            dct[state_key] = await self.get_state_history(state_key)
        return dct
